home *** CD-ROM | disk | FTP | other *** search
- /*------------------------------------------------------------------------------
-
- File : AIFF.c
-
- Author : Stéphane TAVENARD
-
- $VER: AIFF.c 1.0 (23/06/1995)
-
- (C) Copyright 1995-1995 Stéphane TAVENARD
- All Rights Reserved
-
- #Rev| Date | Comment
- ----|----------|--------------------------------------------------------
- 0 |05/06/1995| Initial revision from file common.c of
- | | MPEG/audio software simulation group ST
- 1 |23/06/1995| Aminet release ST
-
- ------------------------------------------------------------------------
-
- AIFF utilities
-
- ------------------------------------------------------------------------------*/
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <ctype.h>
- #include "AIFF.h"
-
- #define BITS_IN_A_BYTE 8
-
-
- /****************************************************************************
- *
- * Routines to convert between the Apple SANE extended floating point format
- * and the IEEE double precision floating point format. These routines are
- * called from within the Audio Interchange File Format (AIFF) routines.
- *
- *****************************************************************************/
-
- /*
- *** Apple's 80-bit SANE extended has the following format:
-
- 1 15 1 63
- +-+-------------+-+-----------------------------+
- |s| e |i| f |
- +-+-------------+-+-----------------------------+
- msb lsb msb lsb
-
- The value v of the number is determined by these fields as follows:
- If 0 <= e < 32767, then v = (-1)^s * 2^(e-16383) * (i.f).
- If e == 32767 and f == 0, then v = (-1)^s * (infinity), regardless of i.
- If e == 32767 and f != 0, then v is a NaN, regardless of i.
-
- *** IEEE Draft Standard 754 Double Precision has the following format:
-
- MSB
- +-+---------+-----------------------------+
- |1| 11 Bits | 52 Bits |
- +-+---------+-----------------------------+
- ^ ^ ^
- | | |
- Sign Exponent Mantissa
- */
-
- /*****************************************************************************
- *
- * double_to_extended()
- *
- * Purpose: Convert from IEEE double precision format to SANE extended
- * format.
- *
- * Passed: Pointer to the double precision number and a pointer to what
- * will hold the Apple SANE extended format value.
- *
- * Outputs: The SANE extended format pointer will be filled with the
- * converted value.
- *
- * Returned: Nothing.
- *
- *****************************************************************************/
-
- static void double_to_extended( double *pd, char ps[ 10 ] )
- {
- register unsigned long top2bits;
-
- register unsigned short *ps2;
- register IEEE_DBL *p_dbl;
- register SANE_EXT *p_ext;
-
- p_dbl = (IEEE_DBL *) pd;
- p_ext = (SANE_EXT *) ps;
- top2bits = p_dbl->hi & 0xc0000000;
- p_ext->l1 = ((p_dbl->hi >> 4) & 0x3ff0000) | top2bits;
- p_ext->l1 |= ((p_dbl->hi >> 5) & 0x7fff) | 0x8000;
- p_ext->l2 = (p_dbl->hi << 27) & 0xf8000000;
- p_ext->l2 |= ((p_dbl->lo >> 5) & 0x07ffffff);
- ps2 = (unsigned short *) & (p_dbl->lo);
- ps2++;
- p_ext->s1 = (*ps2 << 11) & 0xf800;
- }
-
- /*****************************************************************************
- *
- * extended_to_double()
- *
- * Purpose: Convert from SANE extended format to IEEE double precision
- * format.
- *
- * Passed: Pointer to the Apple SANE extended format value and a pointer
- * to what will hold the the IEEE double precision number.
- *
- * Outputs: The IEEE double precision format pointer will be filled with
- * the converted value.
- *
- * Returned: Nothing.
- *
- *****************************************************************************/
-
- static void extended_to_double( char ps[ 10 ], double *pd )
- {
- register unsigned long top2bits;
-
- register IEEE_DBL *p_dbl;
- register SANE_EXT *p_ext;
-
- p_dbl = (IEEE_DBL *) pd;
- p_ext = (SANE_EXT *) ps;
- top2bits = p_ext->l1 & 0xc0000000;
- p_dbl->hi = ((p_ext->l1 << 4) & 0x3ff00000) | top2bits;
- p_dbl->hi |= (p_ext->l1 << 5) & 0xffff0;
- p_dbl->hi |= (p_ext->l2 >> 27) & 0x1f;
- p_dbl->lo = (p_ext->l2 << 5) & 0xffffffe0;
- p_dbl->lo |= (unsigned long) ((p_ext->s1 >> 11) & 0x1f);
- }
-
- /*****************************************************************************
- *
- * Read Audio Interchange File Format (AIFF) headers.
- *
- *****************************************************************************/
-
- int AIFF_read_headers( FILE *file_ptr, IFF_AIFF *aiff_ptr )
- {
- register long seek_offset;
- register long sound_position;
-
- ChunkHeader Header;
- Chunk FormChunk;
- CommonChunk CommChunk;
- SoundDataChunk SndDChunk;
-
- if( fseek( file_ptr, 0, SEEK_SET ) != 0 ) return -1;
-
- if( fread( &FormChunk, sizeof(Chunk), 1, file_ptr ) != 1 ) return -1;
-
- if( (FormChunk.ckID != IFF_ID_FORM) ||
- (FormChunk.formType != IFF_ID_AIFF) ) return -1;
-
- /*
- * chunks need not be in any particular order
- */
-
- while( fread( &Header, sizeof(ChunkHeader), 1, file_ptr ) == 1 ) {
-
- if( Header.ckID == IFF_ID_COMM ) {
- /*
- * read comm chunk
- */
- if( fread( &CommChunk.numChannels,
- sizeof(CommonChunk) - sizeof(ChunkHeader),
- 1, file_ptr ) != 1 )
- return -1;
-
- extended_to_double( CommChunk.sampleRate, &aiff_ptr->sampleRate);
- aiff_ptr->numChannels = CommChunk.numChannels;
- aiff_ptr->numSampleFrames = CommChunk.numSampleFrames;
- aiff_ptr->sampleSize = CommChunk.sampleSize;
-
- }
- else if( Header.ckID == IFF_ID_SSND ) {
- /*
- * read ssnd chunk
- */
- if( fread( &SndDChunk.offset,
- sizeof(SoundDataChunk) - sizeof(ChunkHeader),
- 1, file_ptr ) != 1 )
- return -1;
-
- aiff_ptr->blkAlgn.offset = SndDChunk.offset;
- aiff_ptr->blkAlgn.blockSize = SndDChunk.blockSize;
- aiff_ptr->sampleType = *(unsigned long *)Header.ckID;
-
- /*
- * record position of sound data
- */
- sound_position = ftell(file_ptr);
-
- /*
- * skip over sound data to look at remaining chunks
- */
- seek_offset = Header.ckSize - sizeof(SoundDataChunk) + sizeof(ChunkHeader);
-
- if( fseek( file_ptr, seek_offset, SEEK_CUR ) != 0 ) return -1;
-
- } else {
- /*
- * skip unknown chunk
- */
- seek_offset = Header.ckSize;
-
- if( fseek( file_ptr, seek_offset, SEEK_CUR ) != 0 ) return -1;
- }
- }
-
- return sound_position ;
- }
-
- /*****************************************************************************
- *
- * Seek past some Audio Interchange File Format (AIFF) headers to sound data.
- *
- *****************************************************************************/
-
- int AIFF_seek_to_sound_data( FILE *file_ptr )
- {
- if( fwrite( NULL,
- sizeof(Chunk) + sizeof(CommonChunk) + sizeof(SoundDataChunk),
- 1, file_ptr ) != 1) return -1;
- return 0;
- }
-
- /*******************************************************************************
- *
- * Write Audio Interchange File Format (AIFF) headers.
- *
- *******************************************************************************/
-
- int AIFF_write_headers( FILE *file_ptr, IFF_AIFF *aiff_ptr )
- {
- Chunk FormChunk;
- CommonChunk CommChunk;
- SoundDataChunk SndDChunk;
-
- FormChunk.ckID = IFF_ID_FORM;
- FormChunk.formType = IFF_ID_AIFF;
- CommChunk.ckID = IFF_ID_COMM;
-
- double_to_extended( &aiff_ptr->sampleRate, CommChunk.sampleRate );
-
- CommChunk.numChannels = aiff_ptr->numChannels;
- CommChunk.numSampleFrames = aiff_ptr->numSampleFrames;
- CommChunk.sampleSize = aiff_ptr->sampleSize;
- SndDChunk.offset = aiff_ptr->blkAlgn.offset;
- SndDChunk.blockSize = aiff_ptr->blkAlgn.blockSize;
- SndDChunk.ckID = aiff_ptr->sampleType;
-
- CommChunk.ckSize = sizeof(CommonChunk) - sizeof(ChunkHeader);
-
- SndDChunk.ckSize = sizeof(SoundDataChunk) - sizeof(ChunkHeader) +
- (CommChunk.sampleSize + BITS_IN_A_BYTE - 1) / BITS_IN_A_BYTE *
- CommChunk.numChannels * CommChunk.numSampleFrames;
-
- FormChunk.ckSize = sizeof(Chunk) + SndDChunk.ckSize + sizeof(ChunkHeader) +
- CommChunk.ckSize;
-
- if( fseek( file_ptr, 0, SEEK_SET ) != 0 ) return -1;
-
- if( fwrite( &FormChunk, sizeof(Chunk), 1, file_ptr ) != 1 ) return -1;
-
- if( fwrite( &CommChunk, sizeof(CommChunk), 1, file_ptr) != 1 ) return -1;
-
- if( fwrite( &SndDChunk, sizeof(SoundDataChunk), 1, file_ptr) != 1 ) return -1;
-
- return 0;
- }
-
-
-